Skip to content

fix(automation): enforce hourly DDD development contract - #1545

Open
seonghobae wants to merge 26 commits into
mainfrom
fix/hourly-ddd-development-contract-20260901
Open

fix(automation): enforce hourly DDD development contract#1545
seonghobae wants to merge 26 commits into
mainfrom
fix/hourly-ddd-development-contract-20260901

Conversation

@seonghobae

@seonghobae seonghobae commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Outcome

Reuses the existing organization commercial-readiness schedule at minute 7 of every hour and makes its product-development lane require a versioned, executable Domain-Driven Design architecture contract. No second cron or competing organization writer is introduced.

Current exact branch

  • exact head: 76b290ca358f1b9d0e0af6df73e3429aae41b895
  • protected main included as second parent: 44a3c740f7c46c06e7500174d4127413f3f581eb
  • the branch therefore retains the newly merged failed-check RCA control-plane changes from fix(governance): dispatch failed-check RCA directly #1541
  • no force push was used

Hourly execution boundary

  • The coordinator remains bounded to at most one review-repair dispatch and one product-development dispatch per pass.
  • Repositories with an enabled dedicated hourly or more-frequent writer retain their writer lease and are not double-dispatched.
  • Repositories without a dedicated writer must expose one active manual default-branch entrypoint with the organization opt-in marker and DDD contract marker.
  • The coordinator refetches the exact default-branch SHA, workflow sources, active writer runs, and open PR state before dispatch.

Executable DDD contract

The repository owns its human-readable product-agent prompt, which may use any language. Eligibility no longer depends on copied English terminology appearing anywhere in raw YAML.

A valid entrypoint must define exactly one root workflow environment with:

CWL_DDD_CONTRACT_VERSION: "1"
CWL_DDD_CONTRACT_CAPABILITIES: >-
  aggregate anti_corruption_layer bounded_context context_map
  directory_ownership domain_event domain_service entity invariant
  minimal_shared_kernel product_gap_baseline repository
  subdomain_classification ubiquitous_language value_object
CWL_PRODUCT_AGENT_PROMPT: |
  <repository-owned product-development instructions>

The same non-comment product-agent command under # cwl-ddd-prompt-binding: v1 must consume both:

--prompt-env CWL_PRODUCT_AGENT_PROMPT
--architecture-contract-env CWL_DDD_CONTRACT_CAPABILITIES

Version one uses an exact closed capability set. Missing, extra, duplicated, misspelled, or unversioned capabilities fail closed. Comments, unrelated or unused YAML, nested or duplicate environment scopes, shell built-ins, malformed quoting, dangling continuations, and flags split across commands do not satisfy the contract.

The capabilities cover core/supporting/generic subdomain classification, Bounded Context, Context Map, Ubiquitous Language, Aggregate, Entity, Value Object, Domain Service, Repository, Domain Event, Invariant, Anti-Corruption Layer, minimal Shared Kernel, directory ownership, and docs/product-technical-gap-baseline.md traceability.

Directory and responsibility repair

Each hourly product increment must identify the owning product responsibility before selecting a repository, then compare the live directory tree, package/module names, API, database objects, tests, and documentation with that responsibility.

Misleading directory ownership, domain behavior hidden in generic utils or common paths, infrastructure imports inside the domain model, cross-context database access, obsolete product names, and customer-visible implementation boundaries are architecture defects. A bounded repair moves implementation together with imports, callers, package manifests, migrations, tests, ADRs, diagrams, and compatibility adapters. A larger coherent migration must be recorded with owner, callers, target context, sequence, and acceptance evidence in docs/product-technical-gap-baseline.md rather than silently deferred.

This does not impose one universal directory template; moves are justified by domain ownership and dependency direction.

Implementation boundary

The previously verified coordinator implementation is preserved byte-for-byte in scripts/ci/organization_commercial_readiness_core.py. The original public/script path remains a compatibility facade that loads the core and injects the new dedicated DDD contract validator. This keeps existing imports and the scheduled command stable while isolating architecture-contract parsing from fleet coordination.

Coordinator credential availability

The scheduled coordinator still prefers PR_REVIEW_MERGE_TOKEN. When absent, the protected default-branch job may exchange its job-bound GitHub OIDC identity for the existing short-lived OpenCode App installation token.

Security properties:

  • job-scoped id-token: write only;
  • exact OpenCode exchange endpoint in the blocked-egress allowlist;
  • 10-second connect and 30-second total timeout on both network calls;
  • strict non-empty JSON string parsing;
  • OIDC and App tokens masked before reuse;
  • no repository GITHUB_TOKEN, reviewer credential, model-provider key, or COPILOT_GITHUB_TOKEN fallback;
  • malformed or unavailable exchange fails closed.

Executable transport-level branch tests for the exchange helper are tracked separately in #1549 so pull-request code never receives a real job-bound OIDC identity.

Verification evidence

Predecessor bounded bootstrap evidence before the review remediation:

  • run 33468148830, job 99732190882;
  • 35 focused tests passed;
  • coordinator 386/386 statements and 88/88 branches, 100%;
  • Python 3.14 warning-as-error execution, compileall, and git diff --check passed.

Review remediation adds focused coverage for multilingual prompt freedom, exact version/capability enforcement, comments-only and unused-YAML rejection, environment scope, same-command binding, shell splitting, malformed commands, compatibility imports, and direct script mode. The permanent PR quality workflow now measures the compatibility facade, coordinator core, and DDD validator together.

All temporary source-fix workflows and scripts were removed from the final branch tree. Current-head GitHub checks and independent reviews are authoritative; predecessor evidence is supporting only.

Supersession

This current-main successor supersedes #1161 and #1233. It does not convert unavailable cross-repository credentials into a successful no-op: the loop either obtains bounded maintainer authority and performs the pass, or fails visibly.

Merge boundary

The PR remains not-merge-ready. Merge only after the unchanged exact head has all required repository/security/coverage/review contexts successful, every actionable review thread resolved, and any policy-required independent approval. Queued, stale, predecessor-head, synthetic-merge-only, skipped-required, or failed evidence is non-passing.

@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 48 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 758e6ada-c31b-4597-9ff5-2065a768624b

📥 Commits

Reviewing files that changed from the base of the PR and between 7f4c5e3 and aa8f69a.

📒 Files selected for processing (16)
  • .github/workflows/agent-review-runtime-quality-ci.yml
  • CHANGELOG.md
  • docs/doctoring/organization-commercial-readiness-loop.md
  • docs/product-technical-gap-baseline.md
  • organization_commercial_readiness_fixtures.py
  • scripts/ci/organization_commercial_readiness_core.py
  • scripts/ci/organization_commercial_readiness_ddd_contract.py
  • scripts/ci/organization_commercial_readiness_loop.py
  • scripts/ci/pr_review_autofix_context.py
  • scripts/ci/pr_review_fix_scheduler.py
  • tests/test_organization_commercial_readiness_loop_credential_contract.py
  • tests/test_organization_commercial_readiness_loop_ddd_binding.py
  • tests/test_organization_commercial_readiness_loop_facade.py
  • tests/test_organization_commercial_readiness_loop_policy.py
  • tests/test_pr_review_fix_scheduler.py
  • tests/test_pr_review_merge_scheduler.py

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Contributor Author

@opencode-agent @cwl-noema-review Please review exact head 38f6422f0220cea9f7df4106964bc358f8f692fe independently. Focus on: (1) OIDC/App-token trust and bounded-failure behavior, (2) workflow permission/egress scope, (3) whether the product-entrypoint predicate truly fails closed when any strategic or tactical DDD term is absent, (4) dedicated-writer lease coexistence without duplicate schedules, and (5) final-tree absence of temporary bootstrap files. Do not reuse predecessor-head verdicts.

devin-ai-integration[bot]

This comment was marked as resolved.

@seonghobae
seonghobae enabled auto-merge (squash) September 1, 2026 04:04

Copy link
Copy Markdown
Contributor Author

@opencode-agent Please repair the current DDD-contract review findings on this existing owner branch and then synchronize current protected main non-destructively (no rebase/force).

  1. Do not accept DDD eligibility from raw YAML phrase presence. Define/parse a narrowly scoped machine-readable DDD contract that is demonstrably connected to the actual product-agent prompt/invocation. Tests must reject all-required-phrases-only-in-comments, env values, unrelated steps, or unused YAML.
  2. Avoid exact prose/capitalization as the semantic gate. Prefer a versioned structured contract/schema with canonical field names/enums so equivalent user-facing prompt wording remains valid while required DDD concepts are machine-checkable.
  3. Upgrade the OIDC/App-token credential tests from string search to executable shell-contract tests with fake curl/jq inputs, covering URL/audience construction, malformed/empty JSON, non-string token, network failure, masking/export, and fail-closed behavior without exposing secrets.

Preserve the single existing hourly coordinator (no additional cron), its bounded dispatch budgets, exact default-branch/head revalidation, dedicated-writer lease behavior, and no COPILOT_GITHUB_TOKEN fallback. Run focused tests plus full 100% coverage/docstrings/compile/diff gates and regenerate exact-head review evidence.

devin-ai-integration[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

@opencode-agent review

The unsafe temporary source-fix workflow/helper have been removed at exact head 1c1532b3d6ce8db5eb7b8fd27b18f6eebcbd389d; their threads are resolved. The three permanent findings remain open and must be implemented directly on this branch: structurally bind the versioned DDD contract to the actual dispatched product-agent input (not raw YAML/comments), replace exact prose matching with canonical schema fields/enums, and execute the OIDC/App-token shell path against fake network/JSON fixtures rather than string-inspecting YAML. After those permanent repairs, merge current protected main non-destructively and regenerate exact-head evidence. Do not recreate a write-capable self-modifying workflow.

devin-ai-integration[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

The temporary write-capable source-fix workflow/helper were reintroduced by the subsequent aeba2182... commit even after their security finding had been fixed. I removed them again on current branch via normal non-force commits c765e6fc... and 69685376.... Fresh source inspection still shows the three permanent findings are not fixed: DDD_CONTRACT_TERMS remains exact prose and has_domain_driven_development_contract() remains raw-YAML substring matching. Do not recreate temporary writer machinery again. I also attempted to convert this PR to Draft while these substantive findings remain, but the GitHub connector's GraphQL mutation currently fails on its own invalid Repository.fullDatabaseId selection; that tool defect is not merge authorization. Keep this PR non-merge-ready until the permanent structured/prompt-bound contract and executable credential tests land directly on the branch.

devin-ai-integration[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

@opencode-agent Please implement the current-head review remediation on exact head 69685376ecb5068a0bdbcee2888e82395312bd18 using the trusted default-branch autofix path. Do not recreate any PR-branch workflow or source-fix helper. Replace raw English phrase matching with a versioned machine-readable DDD capability contract, permit free-form/multilingual prompt prose, and require the prompt plus capability-set environment names to be consumed by the same non-comment product-agent command. Add RED/GREEN policy coverage for comments-only text, unrelated/unused YAML, wrong or duplicate root env scopes, missing capability IDs, wrong bindings, and split commands. Preserve the existing hourly writer lease, OIDC/App-token behavior, docs, changelog, and docs/product-technical-gap-baseline.md; remove all temporary artifacts before publishing. Re-run exact-head focused tests, statement/branch coverage, compileall, and diff checks. Do not merge.

Copy link
Copy Markdown
Contributor Author

Current exact head 69685376ecb5068a0bdbcee2888e82395312bd18 is still not merge-ready on the DDD eligibility boundary. has_domain_driven_development_contract() currently accepts the marker plus exact phrases anywhere in raw YAML, so comments, unrelated env values, or unused keys can satisfy enrollment without the product agent ever receiving the contract; DDD_CONTRACT_TERMS also makes semantically equivalent prompts depend on copied prose. Replace this with a versioned, machine-readable DDD contract schema whose canonical fields/enums are parsed from the actual product-agent prompt/invocation (or a referenced immutable contract passed into that invocation). Add negative tests where all terms appear only in comments, env, unrelated steps, and unused YAML, and positive tests with equivalent structured values independent of prose wording. Keep the completed temporary write-capable source-fix lane deleted; implement the repair directly on this owner branch.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

@opencode-agent review exact head cc3b6b8add7bece45e7dd20ce10a65b653b4d3d7. Revalidation this pass confirmed the formerly actionable DDD binding and canonical-example findings are fixed on current source; all visible review threads are now resolved. The branch is 0 behind protected main and auto-merge is enabled, but integration still requires fresh exact-head required checks and formal review evidence.

Copy link
Copy Markdown
Contributor Author

@opencode-agent current-main convergence pass. All visible Devin threads are resolved on 0a4d66489814fb02568ccad6bb8f61fe30045497, but protected main advanced through #1546 and this branch is now 1 behind. Merge protected main@5686de41660d51a7a7f22b8840dfa6ccfe5ff3f1 into this branch non-destructively (no rebase/force), preserve #1546 reviewer/scheduler behavior, and resolve any overlap by current-main ownership rather than restoring predecessor scheduler code. Do not import unrelated #1567 coverage tests into this DDD product lane; treat #1567 as merged-tree coverage prerequisite until it integrates. Re-run the focused DDD binding/facade/coordinator suites plus full coverage/docstrings, confirm no temporary source-fix workflow/helper reappears, update the exact-head/body evidence, and request fresh OpenCode/Noema review. Keep #1549 as the separate executable credential-transport-test owner.

Copy link
Copy Markdown
Contributor Author

The protected-main production failure in Organization Commercial Readiness Loop run 33483275421 was independently reproduced as a missing-PR_REVIEW_MERGE_TOKEN credential-availability defect. Because this PR is currently a broader stale/non-mergeable DDD bundle, the credential-recovery slice has been extracted onto current main as focused PR #1577 using the same reviewed OIDC→OpenCode App token boundary. #1577 has deterministic RED evidence and an exact-head GREEN quality run (35 tests, coordinator 100% statement/branch coverage). When this DDD branch next reconciles with protected main, absorb the integrated fallback rather than reintroducing a competing implementation.

Copy link
Copy Markdown
Contributor Author

Noema owner-path acceptance finding (2026-09-05 KST): protected central main@3f2f21c577804a473d3c63f87226948dd9b9257a still recognizes manual product entrypoints through the older is_manual_product_entrypoint() contract that requires the entrypoint marker, workflow_dispatch, no schedule, concurrency, and literal NVIDIA_NIM_API_KEY. ContextualWisdomLab/noema cannot adopt that provider-specific credential requirement: its canonical LLM boundary is contextual-orchestrator only (NOEMA_LLM_API_KEY / gateway), with provider/model/key routing owned by CO. Noema #551 tried to remove the local hourly cron before a compatible protected central handoff existed; that PR is now Draft/reopened and explicitly blocked on this owner prerequisite.

Please preserve #1545's central single-writer/DDD intent while ensuring the protected successor admission contract is provider-neutral: repository opt-in + DDD capability/prompt binding + manual dispatch/concurrency should be sufficient, and leaf products must not be required to expose NVIDIA/OpenAI/OpenRouter/Bytez provider credentials. Once that contract is protected, Noema can adopt the exact handshake and remove its local cron atomically with its existing workflow regression. Until then Noema retains its local scheduled writer rather than creating a writer outage or duplicating provider authority.

Copy link
Copy Markdown
Contributor Author

Noema consumer prerequisite refresh (2026-09-05 KST): protected .github/main is now b5e4b55127d3a5658899174f0b34e76b9f203ab6, while this PR remains open/non-mergeable at head 0a4d66489814fb02568ccad6bb8f61fe30045497 and stale base 44a3c740.... Protected-default-branch code search still returns zero matches for CWL_DDD_CONTRACT_VERSION, so the versioned DDD/manual-entrypoint contract is not yet organization authority. Noema #551 therefore keeps its dedicated 47 * * * * writer lease and existing regression intact; deleting the cron before this contract reaches protected truth would create a writer outage rather than a handoff. Please converge this owner lane non-destructively onto current protected main, preserve the exact closed DDD capability contract/manual entrypoint, and land it through normal required gates. Noema will then re-read protected source and implement only the provider-neutral repository handshake before removing its local schedule.

seonghobae and others added 2 commits September 5, 2026 23:44
Three conflicts. One needed relocation rather than a choice:

- .github/workflows/organization-commercial-readiness-loop-quality-ci.yml —
  modify/delete. Main deleted it in ec4521f ("consolidate commercial readiness
  quality"), which moved the contract into
  `agent-review-runtime-quality-ci.yml` (+33) and retired only the standalone
  thin caller (-33). This branch had edited the retired file to bring its two
  new modules into scope, so that intent was relocated into the surviving
  workflow: `organization_commercial_readiness_core.py` and
  `organization_commercial_readiness_ddd_contract.py` added to the `paths:`
  filter, to the changed-scope selector, and to the `compileall` list.

  The coverage `--include` was deliberately left at main's exact
  `'scripts/ci/organization_commercial_readiness_loop.py'`. Widening it to a
  glob broke four contract tests that pin that literal string
  (test_agent_review_runtime_quality_consolidation.py:202,
  test_exact_head_coverage_quality_gate_contract.py:118,
  test_organization_commercial_readiness_loop_policy.py:176, and the negative
  assertion at test_..._import_contract.py:24). Nothing is lost: the two new
  modules live under `scripts/ci`, which the repository-wide coverage gate
  already covers at `fail_under = 100`.

- docs/doctoring/organization-commercial-readiness-loop.md — took main's. Main's
  paragraph is the newer one, it matches the merged workflow's own error text
  ("PR_REVIEW_MERGE_TOKEN or the job-bound OpenCode App token exchange is
  required"), and it carries a "2026-09-01 protected-main credential failure
  RCA" section that explicitly records this PR: the credential boundary was
  extracted to current main so schedule recovery would not be coupled to this
  larger feature, with this PR to absorb it later. This branch's paragraph adds
  no fact main's lacks; its explicit `NVIDIA_NIM_API_KEY` mention is covered by
  main's broader "model-provider keys".

- CHANGELOG.md — kept both sides.

One test fails after this merge and did not fail on either side alone. It is
NOT caused by this resolution and is reported rather than papered over:

  tests/test_organization_commercial_readiness_loop_facade.py::
    test_imported_facade_remains_executable_by_public_module_name

  unmerged head   0 failed, 2242 passed
  after merge     1 failed, 2909 passed        (identical with -p no:randomly)

Minimal deterministic reproduction, found by bisecting the suite:

  pytest tests/test_codeql_default_setup_rollout.py \
         tests/test_organization_commercial_readiness_loop_facade.py \
         -p no:randomly

`test_direct_script_import_falls_back_to_sibling_module` deliberately makes
`import scripts.ci.organization_commercial_readiness_loop` fail so the script
takes its sibling (bare-name) fallback. `monkeypatch` restores `sys.path` and
`__import__` on teardown but not `sys.modules`, so the run leaves both
`organization_commercial_readiness_loop` and a bare-loader
`scripts.ci.organization_commercial_readiness_loop` behind; the facade test's
`runpy.run_module("scripts.ci.organization_commercial_readiness_loop")` then
fails with "loader for organization_commercial_readiness_loop cannot handle
scripts.ci.organization_commercial_readiness_loop". Neither test is wrong
alone — they only collide once this branch and main are in the same tree.

Two `monkeypatch.delitem` repairs were tried on the leaking test and neither
fixed it; both were reverted rather than shipped, so
`tests/test_codeql_default_setup_rollout.py` is byte-identical to main here.

Coverage 100%, interrogate 100%; `ruff check --select F821` clean; workflow
re-parses as valid YAML; zero conflict markers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… first

The merge of origin/main left one failing test,
`test_imported_facade_remains_executable_by_public_module_name`, reproducible
with two files and independent of test ordering:

  pytest tests/test_codeql_default_setup_rollout.py \
         tests/test_organization_commercial_readiness_loop_facade.py \
         -p no:randomly

Root cause is in this branch's facade, not in main's test. Lines 50-54 restamp
the shared `_core` singleton's `__name__/__package__/__loader__/__spec__` on
**every** import of the facade. Measured directly:

  import scripts.ci.organization_commercial_readiness_loop
      -> _core.__spec__.name == "scripts.ci.organization_commercial_readiness_loop"
  import organization_commercial_readiness_loop        (bare sibling fallback)
      -> same object, _core.__spec__.name == "organization_commercial_readiness_loop"
      -> sys.modules["scripts.ci.…"] still points at that object

`runpy.run_module("scripts.ci.organization_commercial_readiness_loop")` then
asks a bare-name loader to load the dotted name and raises. Main's
`test_direct_script_import_falls_back_to_sibling_module` only supplies the
second import; it is not defective. This would break for any caller that
imports the facade under both names, with or without that test.

Two earlier `monkeypatch.delitem(sys.modules, …)` attempts were tried and
reverted: deleting the keys cannot undo the mutation, because both keys point
at the same already-restamped object.

Fix: first import wins. Stamp the public identity only while `_core` still
carries its private core spec. `sys.modules[__name__] = _core` is unchanged, so
the bare alias is still created and direct script execution still works.

Verified:
- 2-file reproduction, both orderings: 27 passed
- negative control: reverting this guard reproduces `1 failed`; restoring it
  returns 27 passed
- direct execution `python organization_commercial_readiness_loop.py
  --organization invalid/name` still exits 2 on the intended argument error
- full suite 2910 passed, 1 skipped, 0 failed (was 1 failed); coverage 100%;
  interrogate 100%

Diagnosis and patch from the concurrent session working the same queue; the
mechanism was re-measured here before applying.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
seonghobae added a commit that referenced this pull request Sep 5, 2026
Four conflicts, including one modify/delete, plus one order-dependent defect
this merge surfaced.

THE PERF CHANGE IS ALREADY ON MAIN. The label_section conflict in
opencode_review_normalize_output.py is the same algorithm on both sides - main's
copy differs only by naming the index 'idx' and carrying a Bolt comment - so
main's side was taken and nothing is lost.

MODIFY/DELETE, relocated rather than dropped:
  main deleted .github/workflows/organization-commercial-readiness-loop-quality-ci.yml
  in ec4521f 'ci(actions): consolidate commercial readiness quality', folding it
  into agent-review-runtime-quality-ci.yml. This branch had modified the deleted
  file to cover the two modules its split creates. Dropping that with the file
  would have left the coordinator ungated: loop.py is now a 54-line facade over a
  892-line core plus a 274-line contract module, and the surviving gate measured
  only 'scripts/ci/organization_commercial_readiness_loop.py'.
  The same four extensions were applied to the consolidated workflow - path
  trigger, suite selection case, coverage --include glob, compileall list - and
  verified by running that job's own command: core 386/386, ddd_contract 195/195,
  facade 30/30, TOTAL 100%.
  Three contract tests pinned the literal include path and were updated to the
  glob with the reason in a comment
  (test_workflow_and_doctoring_contracts, test_commercial_readiness_suite_is_
  selected_and_conditionally_executed, test_organization_loop_contract_moves_to_
  agent_quality_job). Negative control: restoring the literal include makes
  test_workflow_and_doctoring_contracts fail by name.

DEFECT FOUND AND FIXED - facade import identity:
  test_organization_commercial_readiness_loop_facade.py passed alone and failed
  in the full suite. Bisected to tests/test_codeql_default_setup_rollout.py,
  which prepends scripts/ci to sys.path and imports the module under its bare
  top-level name. Probed the resulting state directly: both
  sys.modules['scripts.ci.organization_commercial_readiness_loop'] and
  sys.modules['organization_commercial_readiness_loop'] are the SAME object and
  its __spec__.name is the top-level one, so runpy.run_module on the package name
  raises 'loader for organization_commercial_readiness_loop cannot handle
  scripts.ci.organization_commercial_readiness_loop'.
  The facade restamped _core's identity unconditionally on every import, letting
  the second public name overwrite the first. Guarded so only the first adopter
  stamps it - the same fix this repository already applied for this shape in
  #1545. Verified in both orders.
  This is the branch's facade meeting main's larger suite: the branch head passes
  because main's trigger test is not in its tree.

Evidence:
- uvx ruff check --select F821 scripts/ci tests: All checks passed
- full suite, branch head 0def341 (unmerged): 2243 passed, 0 failed
- full suite, this merge:                      2922 passed, 0 failed
- coverage: TOTAL 100%; interrogate: PASSED (minimum 100.0%)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant